# from rest_framework.viewsets import ModelViewSet
#
# from apps.item.models import Subject
# from apps.item.serializers import SubjectSerializer
#
#
# class SubjectViewSet(ModelViewSet):
#     """视图集"""
#     queryset = Subject.objects.all()
#     serializer_class = SubjectSerializer
import json

from django import http
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, EmptyPage
from django.db import DatabaseError
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection
from django.db.models import Q

from apps.item import models
from apps.item.models import Label, Subject, Difficulty
from utils.response_code import RETCODE


class IndexView(LoginRequiredMixin, View):
    def get(self, request):
        """
        主页
        :param request:
        :return:
        """
        user = request.user
        label = Label.objects.filter(is_deleted=False, user=user)
        context = {
            'user': user,
            'label': label

        }

        return render(request, 'index.html', context=context)


class SubjectsView(LoginRequiredMixin, View):
    """展示和题目选中"""

    def get(self, request):
        """展示题目"""
        user = request.user
        # print(user)
        # print(user.is_authenticated)
        # 用户已登录，查询redis
        redis_conn = get_redis_connection('subjects')
        pl = redis_conn.pipeline()
        # 获取redis中的选中状态
        subject1_selected = redis_conn.smembers('selected_%s' % user.id)
        # 通过for循环删除之前存在的选中的数据，保证每次访问都是一个新的页面
        for i in subject1_selected:
            sub_id = int(i)
            # print(sub_id, "*" * 20)
            pl.srem('subject_%s' % user.id, sub_id)
            pl.execute()
            # print(str(i))
        # print("36", subject1_selected)
        # 再次判断用户是否登录
        if user.is_authenticated:
            # 获取用户选中状态
            # subject_selected = redis_conn.smembers('selected_%s' % user.id)
            subject = Subject.objects.filter(user=user.id, is_deleted=False).order_by("-modify_time")
            # 创建分页器：每页N条记录
            paginator = Paginator(subject, 10)
            # print(paginator.page(1))
            # 获取每页题目数据
            try:
                page_nums = request.GET.get("page")
                page_num = int(page_nums)
            except:
                page_num = 1
            try:
                page_skus = paginator.page(page_num)
                subject_list = []
                for i in page_skus:
                    # print(i.id, 'id')
                    # print(str(str(i.id) in subject_selected))
                    types = ""
                    if i.type == '0':
                        types = '单选题'
                    elif i.type == '1':
                        types = '多选题'
                    elif i.type == '2':
                        types = '问答题'
                    elif i.type == '3':
                        types = '填空题'
                    elif i.type == '4':
                        types = '判断题'
                    else:
                        types = '未知类型'

                    subject_list.append({
                        'id': i.id,
                        'title': i.title,
                        'selected': 'False',  # 将True，转'True'，方便json解析
                        'modify_time': i.modify_time.strftime('%Y-%m-%d %H:%M:%S'),
                        'types': types,
                        'count': 1
                    })
            except EmptyPage:
                # 如果page_num不正确，默认给用户404
                return http.HttpResponseNotFound('empty page')
                # 获取列表页总页数
            total_page = paginator.num_pages
            # print(subject_list)
            # 往前端传递数据
            context = {
                'user': user,
                'subject_list': subject_list,  # 分页后数据
                'total_page': total_page,  # 总页数
                'page_num': page_num,  # 当前页码
            }

            return render(request, 'table_basic.html', context)

    def put(self, request):
        # 实现选中的功能
        # 获取前端发送过来的数据
        json_dict = json.loads(request.body.decode())
        sub_id = json_dict.get('sub_id')
        selected = json_dict.get('selected', True)
        # print(type(sub_id))
        # print(type(selected))
        # 判断参数是否齐全
        if not all([sub_id]):
            return http.HttpResponseBadRequest('缺少参数12')
        try:
            sub = Subject.objects.get(id=sub_id)
        except Subject.DoesNotExist:
            return http.HttpResponseBadRequest("题目不存在")
        if selected:
            if not isinstance(selected, bool):
                return http.HttpResponseBadRequest('参数selected有误')
        # 判断用户是否登录
        user = request.user
        if user.is_authenticated:
            print("-----------")
            # 连接redis数据库
            redis_conn = get_redis_connection('subjects')
            pl = redis_conn.pipeline()
            # 判断是否被选中
            if selected:
                pl.sadd('selected_%s' % user.id, sub_id)
            else:
                # print("23")
                pl.srem('selected_%s' % user.id, sub_id)
                # print("45")
            pl.execute()
            cart_sku = {
                'id': sub_id,
                'selected': selected,
                'title': sub.title,
            }
            # print(cart_sku, "123456")
            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '修改题目成功', 'cart_sku': cart_sku})


class SelectionView(LoginRequiredMixin, View):
    """全选题目"""

    def put(self, request):
        json_dict = json.loads(request.body.decode())
        sub_id = json_dict.get('sub_id')
        selected = json_dict.get('selected', True)
        # 效验参数
        if selected:
            if not isinstance(selected, bool):
                return http.HttpResponseBadRequest('参数selected有误')
        if not all([sub_id]):
            return http.HttpResponseBadRequest('缺少参数12')
        # print(sub_id)
        for i in sub_id:
            # print(type(i.get("id")))
            # 判断用户是否登录
            user = request.user
            if user is not None and user.is_authenticated:
                # 用户已登录
                redis_conn = get_redis_connection('subjects')
                if selected:
                    # 全选
                    redis_conn.sadd('selected_%s' % user.id, i.get("id"))
                    # 取消全选
                    redis_conn.srem('selected_%s' % user.id, i.get("id"))
                return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '全选题目成功'})


class LabelView(LoginRequiredMixin, View):
    """按照分类显示题目"""

    def get(self, request):
        # 获取参数
        lab_id = request.GET.get('p')
        print(lab_id)
        lab_id = lab_id[:lab_id.find('?')]
        user = request.user
        # 连接redis数据库
        redis_conn = get_redis_connection('subjects')
        pl = redis_conn.pipeline()
        # 获取redis中的选中状态
        subject_selected = redis_conn.smembers('selected_%s' % user.id)
        for i in subject_selected:
            sub_id = int(i)
            # print(sub_id, "*" * 20)
            pl.srem('selected_%s' % user.id, sub_id)
            pl.execute()
        if user.is_authenticated:
            print("1")
            label = Label.objects.get(id=lab_id)
            print("2")
            subject = Subject.objects.filter(user=user.id, is_deleted=False, label=label).order_by("-modify_time")
            print(subject)
            # 创建分页器：每页N条记录
            paginator = Paginator(subject, 10)
            # 获取每页商品数据
            try:
                page_nums = request.GET.get("page")
                page_num = int(page_nums)
            except:
                page_num = 1
            try:
                page_skus = paginator.page(page_num)
                subject_list = []
                for i in page_skus:
                    if i.type == '0':
                        types = '单选题'
                    elif i.type == '1':
                        types = '多选题'
                    elif i.type == '2':
                        types = '问答题'
                    elif i.type == '3':
                        types = '填空题'
                    elif i.type == '4':
                        types = '判断题'
                    else:
                        types = '未知类型'

                    subject_list.append({
                        'id': i.id,
                        'title': i.title,
                        'selected': "False",  # 将True，转'True'，方便json解析
                        'modify_time': i.modify_time.strftime('%Y-%m-%d %H:%M:%S'),
                        'types': types,
                        'count': 1
                    })
            except EmptyPage:
                # 如果page_num不正确，默认给用户404
                return http.HttpResponseNotFound('empty page')
                # 获取列表页总页数
            total_page = paginator.num_pages
            # print(subject_list)
            # 查询用户是否登录
            context = {
                # 'subject_list': subject_list
                'user': user,
                'subject_list': subject_list,  # 分页后数据
                'total_page': total_page,  # 总页数
                'page_num': page_num,  # 当前页码
            }

            return render(request, 'table_basic.html', context)


class DelView(LoginRequiredMixin, View):
    """删除题目"""

    def delete(self, request):
        json_dict = json.loads(request.body.decode())
        sub_id = json_dict.get('sub_id')
        print(sub_id)
        user = request.user
        if user.is_authenticated:
            try:
                sub = Subject.objects.get(id=sub_id, user=user)
                print(sub)
            except Subject.DoesNotExist:
                return http.HttpResponseBadRequest('题目不存在')
            redis_conn = get_redis_connection('subjects')
            # 获取redis中的选中状态
            subject_selected = redis_conn.smembers('selected_%s' % user.id)
            pl = redis_conn.pipeline()
            # 判断是否被选中
            if str(str(sub_id) in subject_selected):
                pl.srem('selected_%s' % user.id, sub_id)
                # print("12")
            else:
                pass
            pl.execute()
            try:
                sub.is_deleted = True
                sub.label.clear()
                sub.save()
            except Subject.DoesNotExist:
                return http.HttpResponseBadRequest('删除失败')

            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "删除成功"})

    def post(self, request):
        # 选择批量删除
        user = request.user
        # 连接redis
        redis_conn = get_redis_connection('subjects')
        pl = redis_conn.pipeline()
        # 获取redis中的选中状态
        labels_selected = redis_conn.smembers('selected_%s' % user.id)
        print(labels_selected)
        for i in labels_selected:
            print(i)
            try:
                subject = Subject.objects.get(id=int(i), user=user)
                print(subject)
                subject.is_deleted = True
                subject.label.clear()
                subject.save()
            except Subject.DoesNotExist:
                return http.JsonResponse({'code': RETCODE.DEL, 'errmsg': '删除题目失败'})
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '删除分类成功'})


class LabelsView(LoginRequiredMixin, View):
    """显示标签，添加标签，选择标签"""

    def get(self, request):
        """展示标签"""
        user = request.user
        print(user)
        print(user.is_authenticated)
        # 用户已登录，查询redis
        redis_conn = get_redis_connection('labels')
        pl = redis_conn.pipeline()
        # 获取redis中的选中状态
        labels_selected = redis_conn.smembers('labels_%s' % user.id)
        for i in labels_selected:
            sub_id = int(i)
            # print(sub_id, "*" * 20)
            pl.srem('labels_%s' % user.id, sub_id)
            pl.execute()
        if user.is_authenticated:
            label = Label.objects.filter(Q(id__gt=1) & Q(is_deleted=False) & Q(user=user)).order_by("-modify_time")
            # 创建分页器：每页N条记录
            paginator = Paginator(label, 10)
            print(paginator.page(1))
            # 获取每页题目数据
            try:
                page_nums = request.GET.get("page")
                page_num = int(page_nums)
            except:
                page_num = 1
            try:
                page_skus = paginator.page(page_num)
                subject_list = []
                for i in page_skus:
                    subject_list.append({
                        'id': i.id,
                        'title': i.name,
                        'selected': "false",  # 将True，转'True'，方便json解析
                        'modify_time': i.modify_time.strftime('%Y-%m-%d %H:%M:%S'),
                        'nums': len(Subject.objects.filter(label=i.id)),
                        'count': 1
                    })
            except EmptyPage:
                # 如果page_num不正确，默认给用户404
                return http.HttpResponseNotFound('empty page')
                # 获取列表页总页数
            total_page = paginator.num_pages
            # print(subject_list)
            # 查询用户是否登录
            context = {
                # 'subject_list': subject_list
                'user': user,
                'subject_list': subject_list,  # 分页后数据
                'total_page': total_page,  # 总页数
                'page_num': page_num,  # 当前页码
            }

            return render(request, 'label.html', context)

    def post(self, request):
        json_dict = json.loads(request.body.decode())
        labels = json_dict.get('name')
        user = request.user
        if user.is_authenticated:
            if not all([labels]):
                return http.JsonResponse({'code': "7401", 'errmsg': '数据异常，添加失败'})

            label = Label.objects.filter(name=labels)
            for i in label:
                if i.name == labels:
                    return http.JsonResponse({'code': "7402", 'errmsg': '分类已有，添加失败'})
            try:
                label = Label.objects.create(name=labels)
            except Label.DoesNotExist:
                return http.JsonResponse({'code': "7403", 'errmsg': '添加失败'})
            return http.JsonResponse({'code': "0", 'errmsg': '分类添加成功'})

    def put(self, request):
        # 获取前端发送过来的数据
        json_dict = json.loads(request.body.decode())
        sub_id = json_dict.get('sub_id')
        selected = json_dict.get('selected', True)
        # print(type(sub_id))
        # print(type(selected))
        # 判断参数是否齐全
        if not all([sub_id]):
            return http.HttpResponseBadRequest('缺少参数12')
        try:
            sub = Subject.objects.get(id=sub_id)
        except Subject.DoesNotExist:
            return http.HttpResponseBadRequest("题目不存在")
        if selected:
            if not isinstance(selected, bool):
                return http.HttpResponseBadRequest('参数selected有误')
        # 判断用户是否登录
        user = request.user
        if user.is_authenticated:
            print("-----------")
            # 连接redis数据库
            redis_conn = get_redis_connection('labels')
            pl = redis_conn.pipeline()
            # 判断是否被选中
            if selected:
                pl.sadd('labels_%s' % user.id, sub_id)
            else:
                # print("23")
                pl.srem('labels_%s' % user.id, sub_id)
                # print("45")
            pl.execute()
            cart_sku = {
                'id': sub_id,
                'selected': selected,
                'title': sub.title,
            }
            # print(cart_sku, "123456")
            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '修改题目成功', 'cart_sku': cart_sku})


class LabelSelectView(LoginRequiredMixin, View):
    """全选题目"""

    def put(self, request):
        json_dict = json.loads(request.body.decode())
        sub_id = json_dict.get('sub_id')
        selected = json_dict.get('selected', True)
        # 效验参数
        if selected:
            if not isinstance(selected, bool):
                return http.HttpResponseBadRequest('参数selected有误')
        if not all([sub_id]):
            return http.HttpResponseBadRequest('缺少参数12')
        print(sub_id)
        print(type(sub_id))
        for i in sub_id:
            print(i.get("id"))
            print(i)
            # print(type(i.get("id")))
            # 判断用户是否登录
            user = request.user
            if user is not None and user.is_authenticated:
                # 用户已登录
                redis_conn = get_redis_connection('labels')
                if selected:
                    # 全选
                    redis_conn.sadd('labels_%s' % user.id, i.get("id"))
                else:
                    # 取消全选
                    redis_conn.srem('labels_%s' % user.id, i.get("id"))
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '全选题目成功'})


class LabelSettlementView(LoginRequiredMixin, View):
    """删除标签"""

    def post(self, request):
        user = request.user
        # 连接redis
        redis_conn = get_redis_connection('labels')
        pl = redis_conn.pipeline()
        # 获取redis中的选中状态
        labels_selected = redis_conn.smembers('labels_%s' % user.id)
        print(labels_selected)
        for i in labels_selected:
            try:
                label = Label.objects.get(id=int(i))
                print(label)
                label.is_deleted = True
                try:
                    subs = Subject.objects.filter(label=label)
                    la = Label.objects.filter(id=1)
                    print(subs)
                    for su in subs:
                        su.label.clear()
                        su.label.add(*la)
                    label.save()

                except Subject.DoesNotExist:
                    return http.JsonResponse({'code': RETCODE.DEL, 'errmsg': '删除分类失败'})

            except Label.DoesNotExist:
                return http.JsonResponse({'code': RETCODE.DEL, 'errmsg': '分类不存在'})
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '删除分类成功'})

    def delete(self, request):
        json_dict = json.loads(request.body.decode())
        sub_id = json_dict.get('sub_id')
        print(sub_id)
        user = request.user
        if user.is_authenticated:
            try:
                label = Label.objects.get(id=int(sub_id))
                print(label)
            except Subject.DoesNotExist:
                return http.HttpResponseBadRequest('分类不存在')
            redis_conn = get_redis_connection('labels')
            # 获取redis中的选中状态
            subject_selected = redis_conn.smembers('labels_%s' % user.id)
            pl = redis_conn.pipeline()
            # 判断是否被选中
            if str(str(sub_id) in subject_selected):
                pl.srem('selected_%s' % user.id, sub_id)
                # print("12")
            else:
                pass
            pl.execute()
            try:
                label.is_deleted = True
                try:
                    subs = Subject.objects.filter(label=label)
                    la = Label.objects.filter(id=1)
                    print(subs)
                    for su in subs:
                        su.label.clear()
                        su.label.add(*la)
                    label.save()
                except Subject.DoesNotExist:
                    return http.JsonResponse({'code': RETCODE.DEL, 'errmsg': '删除分类失败'})

            except Subject.DoesNotExist:
                return http.HttpResponseBadRequest('删除失败')

            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "删除成功"})


class CheckedView(LoginRequiredMixin, View):
    """添加题目获取中获取选择的分类"""

    def post(self, request):
        user = request.user
        json_dict = json.loads(request.body.decode())
        id = json_dict.get('id')
        print(type(id))
        redis_conn = get_redis_connection('checked')
        pl = redis_conn.pipeline()

        # 获取redis中的选中状态
        labels_selected = redis_conn.smembers('checked_%s' % user.id)
        print(len(labels_selected), "*" * 20)
        if len(labels_selected) == 0:
            pl.sadd('checked_%s' % user.id, id)
            pl.execute()
        else:
            for i in labels_selected:
                print(i)
                if id == int(i):
                    pl.srem('checked_%s' % user.id, id)
                    print("12")
                else:
                    pl.sadd('checked_%s' % user.id, id)
                    print("34")
                pl.execute()
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '成功'})


class AddView(LoginRequiredMixin, View):
    """添加选择题目"""

    def get(self, request):
        lab_id = request.GET.get('a')
        print(lab_id, type(lab_id), '*' * 50)

        user = request.user
        # 连接redis
        redis_conn = get_redis_connection('checked')
        pl = redis_conn.pipeline()
        # 获取redis中的数据
        labels_selected = redis_conn.smembers('checked_%s' % user.id)
        # 清空redis
        for i in labels_selected:
            print(i, "*" * 20)
            sub_id = int(i)
            # print(sub_id, "*" * 20)
            pl.srem('checked_%s' % user.id, sub_id)
            pl.execute()
        lab_id = request.GET.get('a')
        print(lab_id)
        user = request.user
        # 获取分类的数据
        label = Label.objects.filter(Q(id__gt=1) & Q(is_deleted=False))
        print(label)
        context = {
            'user': user,
            'label': label
        }
        if lab_id == '0':
            return render(request, 'single.html', context=context)
        elif lab_id == '1':
            return render(request, 'multiple.html', context=context)
        elif lab_id == '2':
            return render(request, 'essay.html', context=context)
        elif lab_id == '4':
            return render(request, 'true.html', context=context)

    def post(self, request):
        user = request.user
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')  # 题目
        A = json_dict.get('A')  # A选项
        B = json_dict.get('B')
        C = json_dict.get('C')
        D = json_dict.get('D')
        analysis = json_dict.get('analysis')  # 解析
        answer = json_dict.get('answer')  # 答案
        lists = json_dict.get('list')  # 难度
        dif = Difficulty.objects.filter(name=lists).first()
        print(dif)
        if not all([title, A, B, C, D, lists, answer]):
            return http.JsonResponse({'code': "7410", 'errmsg': '数据异常，添加失败'})
        redis_conn = get_redis_connection('checked')
        labels_selected = redis_conn.smembers('checked_%s' % user.id)
        try:
            su = Subject.objects.create(title=title, difficulty=dif, choice_a=A, choice_b=B, choice_c=C, choice_d=D,
                                        answer=answer, analysis=analysis, user=user, type="0")
            if len(labels_selected) == 0:
                la = Label.objects.filter(id=1)
                su.label.add(*la)
            else:
                for i in labels_selected:
                    la = Label.objects.filter(id=i)
                    su.label.add(*la)
        except Subject.DoesNotExist:
            http.JsonResponse({'code': "7403", 'errmsg': '添加失败'})
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "添加成功"})


class AddEssayView(LoginRequiredMixin, View):
    def post(self, request):
        user = request.user
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')  # 题目

        analysis = json_dict.get('analysis')  # 解析
        answer = json_dict.get('answer')  # 答案
        print(answer)
        lists = json_dict.get('list')  # 难度
        dif = Difficulty.objects.filter(name=lists).first()
        print(dif)
        if not all([title, lists, answer]):
            return http.JsonResponse({'code': "7410", 'errmsg': '数据异常，添加失败'})
        redis_conn = get_redis_connection('checked')
        labels_selected = redis_conn.smembers('checked_%s' % user.id)
        try:
            su = Subject.objects.create(title=title, difficulty=dif, note=answer, analysis=analysis, user=user,
                                        type="2")
            if len(labels_selected) == 0:
                la = Label.objects.filter(id=1)
                su.label.add(*la)
            else:
                for i in labels_selected:
                    la = Label.objects.filter(id=i)
                    su.label.add(*la)
        except Subject.DoesNotExist:
            http.JsonResponse({'code': "7403", 'errmsg': '添加失败'})
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "添加成功"})


class AddMultipleView(LoginRequiredMixin, View):
    def post(self, request):
        user = request.user
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')  # 题目
        A = json_dict.get('A')  # A选项
        B = json_dict.get('B')
        C = json_dict.get('C')
        D = json_dict.get('D')
        E = json_dict.get('E')
        F = json_dict.get('F')
        analysis = json_dict.get('analysis')  # 解析
        answer = json_dict.get('answer')  # 答案
        answer = answer[:-1]
        print(type(answer))
        lists = json_dict.get('list')  # 难度
        dif = Difficulty.objects.filter(name=lists).first()
        if not all([title, A, B, C, D, E, F, lists, answer]):
            return http.JsonResponse({'code': "7410", 'errmsg': '数据异常，添加失败'})
        redis_conn = get_redis_connection('checked')
        labels_selected = redis_conn.smembers('checked_%s' % user.id)
        try:
            su = Subject.objects.create(title=title, difficulty=dif, choice_a=A, choice_b=B, choice_c=C, choice_d=D,
                                        choice_e=E, choice_f=F, answer=answer, choice_num=7, analysis=analysis,
                                        user=user, type="1")
            if len(labels_selected) == 0:
                la = Label.objects.filter(id=1)
                su.label.add(*la)
            else:
                for i in labels_selected:
                    la = Label.objects.filter(id=i)
                    su.label.add(*la)
        except Subject.DoesNotExist:
            http.JsonResponse({'code': "7403", 'errmsg': '添加失败'})
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "添加成功"})


class AddTrueView(LoginRequiredMixin, View):
    def post(self, request):
        user = request.user
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')  # 题目
        analysis = json_dict.get('analysis')  # 解析
        answer = json_dict.get('answer')  # 答案
        lists = json_dict.get('list')  # 难度
        dif = Difficulty.objects.filter(name=lists).first()
        print(dif)
        if not all([title, lists, answer]):
            return http.JsonResponse({'code': "7410", 'errmsg': '数据异常，添加失败'})
        redis_conn = get_redis_connection('checked')
        labels_selected = redis_conn.smembers('checked_%s' % user.id)
        try:
            su = Subject.objects.create(title=title, difficulty=dif,
                                        answer=answer, analysis=analysis, user=user, type="4")
            if len(labels_selected) == 0:
                la = Label.objects.filter(id=1)
                su.label.add(*la)
            else:
                for i in labels_selected:
                    la = Label.objects.filter(id=i)
                    su.label.add(*la)
        except Subject.DoesNotExist:
            http.JsonResponse({'code': "7403", 'errmsg': '添加失败'})
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "添加成功"})
